/**
 * Copyright (C) 2011 KingCore Science & Technology CO,.LTD. All rights reserved.
 * XNS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

/**
 * Copyright (C) 2002-2011 WUZEWEN. All rights reserved.
 * WUZEWEN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 * This software is the confidential and proprietary information of
 * WuZeven, Personal. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with WuZeven.
 */

package com.kingcore.director.search.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Event;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.ResourceBundle;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;

import wzw.swing.table.PlainTable;
import wzw.swing.table.PlainTableModel;
import wzw.util.I18nUtil;
import wzw.util.I18nUtils;
import wzw.util.StringUtils;

import com.kingcore.director.DirectorConstants;
import com.kingcore.director.base.ui.DirectorPanel;
import com.kingcore.director.core.util.DirectorComponentUtils;
import com.kingcore.director.core.util.DirectorFileUtils;
import com.kingcore.director.core.util.StopWatch;
import com.kingcore.director.main.Main;
import com.kingcore.director.main.MainFrame;
import com.kingcore.director.main.MiniDialog;
import com.kingcore.director.resourcemaster.ui.ResourceMasterMainPanel;

/**
 * <p>java class file describe</p>
 * @author Zeven on 2011-2-21
 * @version	1.0
 * @see		Object#equals(java.lang.Object)
 * @since	JDK5
 */

public class LocalSearchMainPanel extends DirectorPanel 
	implements ActionListener, MouseListener, KeyListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
    //log object
	private final static Logger log = Logger.getLogger(LocalSearchMainPanel.class);

	private static final int MainTable_Column_Count = 4;
	private static final int MainTable_Column_Index_Name = 0;
	private static final int MainTable_Column_Index_FilePath = 1;
	private static final int MainTable_Column_Index_Size = 2;
	private static final int MainTable_Column_Index_LastModified = 3;
	private static final int Search_Result_Max_Num = 1500;
	
	public static final String[] MainTable_Headers = {"Name", "Path", "Size", "Data Modified"};
	public static final int[] MainTable_Columns_Width = {260, Main.MainFrame_Size_Width-260-80-DirectorConstants.Table_TimeColumn_Width, 80, DirectorConstants.Table_TimeColumn_Width};

	/**
	 * <p>java method describe</p>
	 * @author Zeven on 2011-2-21
	 * @param args
	 */
	public static void main(String[] args) {
		File file = new File("E:/WZW_Documents/readme.woo");
		System.out.println(file.getAbsolutePath());
		System.out.println(file.getParent() );

	}

	private JSplitPane mainSplitPane;
	private JTextField keywordTextField;
	
	public JTextField getKeywordTextField(){
		if (keywordTextField==null) {
			keywordTextField=new JTextField();
			
			keywordTextField.addActionListener(this);
			keywordTextField.setToolTipText("Key word input(Ctrl+F)");
			keywordTextField.getDocument().addDocumentListener(new DocumentListener(){
				public void insertUpdate(DocumentEvent e) {
	                 final String searchWord = keywordTextField.getText();
	                 log.debug("insertUpdate kw="+searchWord );
	                 if (searchWord==null || searchWord.trim().length()<1) {
	                 	return ;
	                 }else{
//	         	    	SortableTableModel stm = (SortableTableModel)mainTable.getModel();
//	         	    	((DefaultTableModel)stm.getTableModel()).setRowCount(0);// 清除原有行
	                 }
	                 
	                 doSearch(searchWord);
//	                 new Thread(){
//						  public void run() {
//				               doSearch(searchWord);  //启动新线程，增加用户体验，界面textField马上显示文字
//						  }
//	                 }.start();
	               // throw new UnsupportedOperationException("Not supported yet.");
	               // System.out.print("1");
	               // System.out.println(jTextField1.getText());
	            }

	            public void removeUpdate(DocumentEvent e) {
	                 final String searchWord = keywordTextField.getText();
	                 log.debug("removeUpdate kw="+searchWord );
	                 if (searchWord==null || searchWord.trim().length()<1) {
	                 	return ;
	                 }else{  // following must out of new thread.
//	         	    	SortableTableModel stm = (SortableTableModel)mainTable.getModel();
//	         	    	((DefaultTableModel)stm.getTableModel()).setRowCount(0);// 清除原有行
	                 }
	                 
		             doSearch(searchWord); 
//	                 new Thread(){
//						  public void run() {
//				               doSearch(searchWord);  //启动新线程，增加用户体验，界面textField马上显示文字
//						  }
//	                 }.start();
	                 
	            }

	            public void changedUpdate(DocumentEvent e) {
	                //JOptionPane.showMessageDialog(null, "请填写完整！");
	                 String searchWord = keywordTextField.getText();
	                 log.debug("kw="+searchWord);
	                 
	            }
	        });
			
			keywordTextField.addKeyListener(this);
			
		}
		return keywordTextField;
	}

	private static String latestSearchWord = null; //
	public static boolean isSearching = false; // 
	public static boolean isBuildingIndexFile = false; // 
	private void doSearch(String searchWord){
        if (searchWord==null || searchWord.trim().length()<1) {
        	return ;
        }
        searchWord = searchWord.trim();
//        try {
//        	do{
//        		Thread.sleep( DirectorConstants.User_Input_Delay );
//        		if (!trueSearchWord.equals(searchWord)) { // 如果被后来的改变了，放弃本次检索
//        			return;
//        		}
//        	}while(isSearching);
//        	
//		} catch (InterruptedException e2) {
//			e2.printStackTrace();
//		}
		if ( searchWord.equals(latestSearchWord)) { // 如果被后来的改变了，放弃本次检索
			return;
		}
		
		if (isBuildingIndexFile) {
			JOptionPane.showMessageDialog(this, "正在创建索引文件，请创建完成后再搜索！");
			return;
		}
		
		log.debug("begin kw="+searchWord);      
		isSearching = true ; 
		long seartStartTime = System.currentTimeMillis();
        // using lucene to query data
		int resultRowNum = LocalSearchMainPanel.Search_Result_Max_Num;
		int endRow = 0;
		
		StopWatch stopWatch = new StopWatch();
		try {
			stopWatch.start();
			fileIndexManager = getFileIndexManager();
			if (fileIndexManager==null) {  //不能创建对象的时候
				return;
			}
			currentStatusInfor = status_Searching;
	        setStatus(StatusBar_Index_One, currentStatusInfor);  
	        ///baseFrame.getStatusBar().updateUI();
			log.info(stopWatch.watchPoint());
			List<Document> luceneSearchresult = fileIndexManager.query(searchWord, new String[]{LocalFileIndexBuilder.Field_For_Index}, 0, resultRowNum);
			List<Map<String,String>> mapList = new ArrayList<Map<String,String>>();
			int startRow = 0; //getStartRow(currentPage, rowsPerPage);
			endRow = luceneSearchresult.size(); // getEndRow(currentPage, rowsPerPage, luceneSearchresult.size());
			for(int i = startRow; i < endRow; i++) {
				Document d = luceneSearchresult.get(i);
				//d.get
				Map<String,String> m = new HashMap<String,String>();
				String field1 = d.get( LocalFileIndexBuilder.Field_For_Index );
				String field1s[] = field1.split(LocalFileIndexBuilder.DELIMETER);
				m.put("name", field1s[MainTable_Column_Index_Name]);
				//m.put("OBJ_NAME", field1s[MainTable_Column_Index_LastModified]); // add by wzw
				String field2 = d.get( LocalFileIndexBuilder.Field_Not_Index);
				String field2s[] = field2.split(LocalFileIndexBuilder.DELIMETER);
				m.put("path", field2s[MainTable_Column_Index_Name]);
				String sizeStr = null;
				try {
					int size = Integer.parseInt(field2s[MainTable_Column_Index_FilePath]); //JTable的列编号跟Lucene的列编号并不对应
					size = size/1000 + 1;
					sizeStr = size +"KB";
				} catch (Exception e) {
					//e.printStackTrace();
				}
				String lastModifiedStr = null;
				try {
					Timestamp tsp = new Timestamp( Long.parseLong( field2s[MainTable_Column_Index_Size] ));
					lastModifiedStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(tsp);
				} catch (Exception e) {
					e.printStackTrace();
				}
				
				m.put("size", sizeStr);
				m.put("lastModified", lastModifiedStr);
				mapList.add(m);
			}
			PlainTableModel stm = mainTable.getModel();
	 
			stm.setStartTableModelListener(true);
			fillTable(mapList); 
			//fileIndexManager.close();
			isSearching = false;
			log.info( stopWatch.watchPoint());
		
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			isSearching = false;
			e1.printStackTrace();
		}
		log.debug("end kw="+searchWord);
    	// 延时，以避免过多检索
        latestSearchWord = searchWord;		
        double allTime = ((float)(System.currentTimeMillis()-seartStartTime))/(1000.00);
		DecimalFormat df = new DecimalFormat("0.000");//格式化小数，不足的补0
		String allTimeStr = df.format(allTime);//返回的是String类型的

        ///JOptionPane.showMessageDialog(this.mainFrame, "test-"+searchWord);
		String tstr_info = StringUtils.replace(stutas_searchResultInfo,"${rowCount}", endRow+"");
		currentStatusInfor = StringUtils.replace(tstr_info,"${costTime}", allTimeStr);//endRow+" "+stutas_resultCount+" ("+allTimeStr+" "+stutas_seconds+")";
        setStatus(StatusBar_Index_One, currentStatusInfor);        
	}
	
	private String stutas_searchResultInfo = "${rowCount} results cost ${costTime} seconds";
	private String status_Searching = "Searching...";
	
	private LocalFileIndexManager fileIndexManager;
	private LocalFileIndexManager getFileIndexManager() throws IOException {
		if (fileIndexManager==null) {
			File indexFile = new File(LocalFileIndexBuilder.LocalFileSystem_INDEX);
			if (!indexFile.exists() || indexFile.list().length<1) {
				if(JOptionPane.showConfirmDialog(this,"第一次搜索需要检索本地磁盘，简历索引，确认执行吗？(可能要花十几分钟或更长的时间)","提示",JOptionPane.OK_CANCEL_OPTION)
		 				!=JOptionPane.OK_OPTION)
					return null;
  
				this.executeRefreshLocalSearch();
				return null;   ////多线程，故要返回，否则执行后面的
			}
			fileIndexManager = new LocalFileIndexManager(LocalFileIndexBuilder.LocalFileSystem_INDEX);
		
		}
		return fileIndexManager;
	}

	 /**
	  *  件
	  *
	  */
	 public void executeRefreshLocalSearch() {
//		if(JOptionPane.showConfirmDialog(this,"确认检索本地磁盘，刷新本地搜索数据库吗？(可能要花几分钟或更长的时间)","提示",JOptionPane.OK_CANCEL_OPTION)
//	 				!=JOptionPane.OK_OPTION)
//			return;
		LocalSearchMainPanel.isBuildingIndexFile = true;
		currentStatusInfor = statusBar_creatingIndexFiles; //"Creating index files ...";
		setStatus(StatusBar_Index_One, currentStatusInfor);
		LocalFileIndexEngine life = new LocalFileIndexEngine( this.mainFrame );
		life.refreshAllLocalFile(); 
		    
//		JOptionPane.showMessageDialog(this, info );
	 }
	 
	private MainFrame mainFrame = null; 
	public LocalSearchMainPanel(MainFrame mainFrame){
		super(mainFrame); 

		this.mainFrame = mainFrame;
		initializeInterface();	
		
		this.addKeyListener( this );
		
		this.update(null, null);		
		constructAfter();
	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		this.fileIndexManager.close();  //注：java的finalize方法不一定保证会被调用
	}

	public void refreshView(){
		super.refreshView();
		
		// please do something in subclass.
		// set keywordTextField focus is canceled.
//		keywordTextField.requestFocusInWindow();
//		keywordTextField.setFocusable(true);
//		keywordTextField.requestFocus();					
		setStatus(StatusBar_Index_One, currentStatusInfor);
		getKeywordTextField().requestFocusInWindow(); //这里指定焦点会造成Tab键切换Panel有些不好的体验。
	}
	
	private void initializeInterface(){
		
		this.setLayout( new BorderLayout() );
		this.add( getMainSplitPane(), BorderLayout.CENTER );
		this.add( getStatusBar(true), BorderLayout.SOUTH);
//		this.addFocusListener(new FocusListener(java.awt.event.FocusEvent fe){
//	        public void focusGained(){
//
//	             textfield.requestFocus();
//	        }		
//		}); 
		this.addComponentListener(new ComponentAdapter() {
			public void componentShown(ComponentEvent e) {
				log.debug("panel:shown");
				//refreshView();  // 不建议这调用，事件不可靠，在上层tabpage切换时候主动调用。
			}
		});

		this.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				log.debug("panel:keyPressed");
			    // 判断按下的是否是向下的方方向键，
			    if (e.getKeyCode() == KeyEvent.VK_DOWN) {
					keywordTextField.requestFocusInWindow();
					keywordTextField.requestFocus();
			    }
			   }
			  });
		
		
	}
	
	private JSplitPane getMainSplitPane(){		
		if (mainSplitPane==null) {
			mainSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, false);
			mainSplitPane.add( getKeywordTextField(), JSplitPane.TOP );
			mainSplitPane.add( getBottomScrollPanel(), JSplitPane.BOTTOM);
			
			// mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,false,getTree(),getTable());
			mainSplitPane.setDividerLocation(25);  //200);
			mainSplitPane.setBorder(null);
			///mainSplitPane.setEnabled(false);  //不能手动改变大小 //设置这个会导致光标不变成输入状态
			// 设置JSplitPane是否可以展开或收起(如同文件总管一般)，设为true表示打开此功能。
			mainSplitPane.setOneTouchExpandable(true);
			// 设置分隔线宽度的大小，以pixel为计算单位。
			mainSplitPane.setDividerSize(1); 
			
		}
		return mainSplitPane;
	}
	
	private JScrollPane bottomScrollPanel;
	private JPopupMenu popupMenuForTable;
	private JMenuItem jpmi_MainTable_Open;
	private JMenuItem jpmi_MainTable_OpenPath;
	private JMenuItem jpmi_MainTable_OpenPath_In_FileExplorer;
	private JMenuItem jpmi_MainTable_Add2FavoriteFile;
	private JMenuItem jpmi_MainTable_Rename;
	private JMenuItem jpmi_MainTable_Delete;
	
	private PlainTable mainTable; 
	private JScrollPane getBottomScrollPanel(){
		if (bottomScrollPanel==null) {
			bottomScrollPanel = new JScrollPane();
			//rightScrollPanel.setBounds(new java.awt.Rectangle(158,this.clientTop,432, this.clientHeight));
			
			//rightScrollPanel.setLayout(new BorderLayout());
			//rightScrollPanel.setLayout( new BorderLayout() );
			bottomScrollPanel.setViewportView(getMainTable());	//getRightPane()
			
		}
		return bottomScrollPanel;
	}
	
	public void fillTable(List<Map<String,String>> members){
		PlainTableModel sortableTableModel = mainTable.getModel();
		DefaultTableModel tableModel = (DefaultTableModel)sortableTableModel.getTableModel();
//		DefaultTableModel tableModel = (DefaultTableModel)mainTable.getModel();
		  tableModel.setRowCount(0);// 清除原有行
		  
		  // 填充数据
		  for(Map<String,String> member:members){
		    String[] arr=new String[4];
		    arr[MainTable_Column_Index_Name]=member.get("name");
		    arr[MainTable_Column_Index_FilePath]=member.get("path");
		    arr[MainTable_Column_Index_Size]=member.get("size")==null?"":member.get("size");
		    arr[MainTable_Column_Index_LastModified]=member.get("lastModified");
		    
		    // 添加数据到表格
		    tableModel.addRow(arr);
		  }
		  
		  // 更新表格
		  mainTable.invalidate();
		}
	
	private PlainTable getMainTable(){
		if (mainTable==null) {
			mainTable = new PlainTable();	 
		    Object[][] data = {
		       {"explorer.exe", "C:\\WINDOWS", "956.8k", "2009-2-21 11:20:58"},
		       {"hosts", "C:\\WINDOWS\\system32\\drivers\\etc", "1k", "2009-2-15 08:25:08"}
		    };
		    
		    // A DefaultTableModel object is created and initialized with some
		    // data and headers.

		    //DefaultTableModel dtm = new DefaultTableModel(2, 3);
		    //DefaultTableModel dtm = new UneditableTableModel(2, 3);
		    DefaultTableModel dtm = new DefaultTableModel(2, 3); //no new methods
		    dtm.setDataVector(data, MainTable_Headers );
//		    RowSorter sorter = new TableRowSorter(dtm);
		    PlainTableModel sorter = new PlainTableModel( dtm, mainTable.getTableHeader());
		    sorter.setColumnEditable( MainTable_Column_Index_Name );
		    sorter.setColumnClass(MainTable_Column_Index_Size, java.lang.Integer.class);
		    mainTable.setModel(sorter);
//		    mainTable.setRowSorter(sorter);
		    
		    mainTable.setGridColor(Color.LIGHT_GRAY);
		    mainTable.setRowSelectionAllowed(true);
		    mainTable.setRowSelectionInterval(1, 1);	
		    mainTable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

		    mainTable.setShowGrid(true);
		    mainTable.getTableHeader().setReorderingAllowed(false);
		    //mainTable.addMouseListener( this );
		     
		    // 更改列宽度
//		    setAllColWith(mainTable);
		    TableColumn tc = null;
		    TableColumnModel tcm = mainTable.getColumnModel(); 
	        for(int i=0; i <MainTable_Columns_Width.length; i++)   {
	            tc   =   tcm.getColumn(i);
	            tc.setPreferredWidth(MainTable_Columns_Width[i]); 
	        }
	        DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
	        renderer.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
	        
	        // column size to right
	        tc = tcm.getColumn( MainTable_Column_Index_Size );//column name
	        tc.setCellRenderer(renderer);
	        
//	        mainTable.getCellEditor().addCellEditorListener(new CellEditorListener()   {
//	        	public   void   editingCanceled(ChangeEvent   e)   {
//	        	System.out.println( "editing   canceled:   ");
//	        	}
//
//	        	public   void   editingStopped(ChangeEvent   e)   {
//	        	System.out.println( "editing   stopped:   ");
//	        	}
//	        	}); 
	        
	        mainTable.addMouseListener( this );
	        mainTable.addKeyListener( this );
	        
	        mainTable.getModel().addTableModelListener(new TableModelListener(){
	        			String synStr = "demo";
						public void tableChanged(TableModelEvent e) {
							synchronized( synStr ){
							if (e.getType() == TableModelEvent.UPDATE) {
								/*
								 * do some thing 获得编辑后单元格得值
								 */
								if (e.getLastRow()>mainTable.getRowCount() || e.getLastRow()<0) {
									return ;
								}
								final String newValue = mainTable.getValueAt(e.getLastRow(),
										MainTable_Column_Index_Name ).toString();
								if (!newValue.equals(tableOldValue) 
										&& newValue!=null 
										&& tableOldValue!=null ) {
									log.info("old value is:"+ tableOldValue + "; newValue="+newValue);
									
									// change file name
									final String path = mainTable.getValueAt(e.getLastRow(), MainTable_Column_Index_FilePath).toString();
									final String size = mainTable.getValueAt(e.getLastRow(), MainTable_Column_Index_Size).toString();
									final String lastModified = mainTable.getValueAt(e.getLastRow(), MainTable_Column_Index_LastModified).toString();
									final String fileUriOld = path + File.separator + tableOldValue;
									final String fileUriNew = path + File.separator + newValue;
									final File fileOld = new File(fileUriOld);
									final File fileNew = new File(fileUriNew);
									
									fileOld.renameTo(fileNew);

									// change lucene index file,
									// create a new thread to do following things to improve user's feeling.
									Thread thread = new Thread(){
										File ff = fileNew;
										  public void run() {

												LocalFileIndexManager im;
												try {
									    			//deal subpath and subfile
									    			if (fileNew.isDirectory()) {
									    				LocalFileIndexEngine.loopFiles(fileUriNew, fileNew.list(), "delete");
									    				LocalFileIndexEngine.loopFiles(fileUriNew, fileNew.list(), "create"); // recreate index file
													}
									    			
													im = new LocalFileIndexManager(LocalFileIndexBuilder.LocalFileSystem_INDEX);
									    			im.deleteIndexByIndex( fileUriOld );
									    			im.close();
//									    			if (IndexReader.isLocked(LocalFileIndexBuilder.LocalFileSystem_INDEX)) {
//									    				IndexReader.unlock(new Directory(LocalFileIndexBuilder.LocalFileSystem_INDEX) );
//													}
									    			
									    			// 3th parameter must be false.
									    			LocalFileIndexBuilder ib = LocalFileIndexBuilder.getInstance(LocalFileIndexBuilder.ANALYZER, LocalFileIndexBuilder.LocalFileSystem_INDEX, false);
									    			Document doc = new Document();
									    			
									    			String sizeNum = "";
									    			if (size!=null && size.endsWith("KB")) {
									    				sizeNum = size.substring(0, size.length()-2);
													}
									    			Long lastModifiedTime = null;
									    			if (lastModified!=null) {
									    				lastModifiedTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(lastModified.trim()).getTime();
													}
									    			StringBuffer notToBeIndexed = new StringBuffer();
									    			notToBeIndexed.append( path ).append(LocalFileIndexBuilder.DELIMETER)
									    				.append(size).append(LocalFileIndexBuilder.DELIMETER)
									    				.append(lastModifiedTime);
									    			
									    			StringBuffer toBeIndexed  = new StringBuffer();
									    			toBeIndexed.append( newValue ).append(LocalFileIndexBuilder.DELIMETER);
									    			
									    			doc.add( new Field( LocalFileIndexBuilder.Field_For_Index, toBeIndexed.toString(), Field.Store.YES, Field.Index.TOKENIZED));
									    			doc.add( new Field( LocalFileIndexBuilder.Field_Not_Index, notToBeIndexed.toString(), Field.Store.YES, Field.Index.NO));
									    			doc.add( new Field( LocalFileIndexBuilder.LocalFileSystem_INDEX, fileUriNew, Field.Store.YES,Field.Index.UN_TOKENIZED));

//									    			ib.addDocumet(doc);
									    			
									    			List<Document> documentList = new ArrayList<Document>();
									    			documentList.add(doc);
									    			ib.writeToIndex(documentList);
									    			ib.close();
									    			
												} catch (Exception e1) {
													log.error(e1);
												}
											  }
										
									};
									
									thread.start();
									try {
										thread.join(); // join or not??
									} catch (InterruptedException e1) {
										e1.printStackTrace();
									} 
								}

								currentStatusInfor = "Rename successfully!";
								setStatus( StatusBar_Index_One, currentStatusInfor);
							}
						}
					}
	        	});
		}
		return mainTable;
		
	}

	private static String File_Type_File = "file";
	private static String File_Type_Folder = "folder";
	
	private int Max_Num_Opened_Once_Time =10 ; //每次最多可打开文件数
	private void doOpenFileOrFolder(String type, boolean openMulti, boolean isShiftDown) { 
		
		int selRows[] = { getMainTable().getSelectedRow() };
		if (openMulti) {
			selRows = getMainTable().getSelectedRows();
		}
		if (selRows==null || selRows.length<1) {
			return;
		}

		int cnt = 1;
		File f = null;
		String fileName = null;
		String filePath = null;
		for (int selRow : selRows) {
			//文件存在否
			fileName = getMainTable().getModel().getValueAt( selRow, MainTable_Column_Index_Name).toString();
			filePath = getMainTable().getModel().getValueAt( selRow, MainTable_Column_Index_FilePath).toString();
			f = new File(filePath);
			if (!f.exists()) {
				continue ;
			}
			if (File_Type_Folder.equals(type)) {
				DirectorFileUtils.openFileLocationQuietly(filePath + File.separator + fileName);
			}else{
				DirectorFileUtils.openFileQuietly(filePath + File.separator + fileName);
			}
			//达到最大数
			if( ++cnt > Max_Num_Opened_Once_Time ){
				break;
			}	
		}
		
		//打开完成后，判断是否需要最小化自己
		if (!"folder_In_FileExplorer".equals(type)
				&& ( (isShiftDown && !"1".equals(DirectorConstants.MinimizeFrame_After_OpenFileOrFolder_Value))
						|| (!isShiftDown && "1".equals(DirectorConstants.MinimizeFrame_After_OpenFileOrFolder_Value)) )) {
	        
			this.mainFrame.setExtendedState( JFrame.ICONIFIED );//最小化.NORMAL
		}
	}
	
	public void actionPerformed(ActionEvent e) {

		Object obj=e.getSource();
		// toolBar
		if( obj==keywordTextField ){ 
			
		}else if( obj == jpmi_MainTable_AddFileOpenTaskAwoke){
			String fileName = getMainTable().getModel().getValueAt(getMainTable().getSelectedRow(), MainTable_Column_Index_Name).toString();
			String filePath = getMainTable().getModel().getValueAt(getMainTable().getSelectedRow(), MainTable_Column_Index_FilePath).toString();
			String fileUri = filePath +File.separator+ fileName;
			this.mainFrame.getReminderMainPanel().executeAddNewFileOpenAwoke(fileUri,fileName);
  		   
		}else if( obj == jpmi_MainTable_Open){
    		doOpenFileOrFolder(File_Type_File, true, DirectorComponentUtils.isShiftDown(e) );
			
		}else if( obj == jpmi_MainTable_OpenPath){ 
    		doOpenFileOrFolder(File_Type_Folder, true, DirectorComponentUtils.isShiftDown(e) ); 
			
		}else if( obj == jpmi_MainTable_OpenPath_In_FileExplorer){ 
			String fileName = getMainTable().getModel().getValueAt(getMainTable().getSelectedRow(), MainTable_Column_Index_Name).toString();
			String filePath = getMainTable().getModel().getValueAt(getMainTable().getSelectedRow(), MainTable_Column_Index_FilePath).toString();
//			if (filePath.endsWith("/")) {
//				filePath = filePath.substring(0, filePath.length()-fileName.length()-1);
//			}else{
//				filePath = filePath.substring(0, filePath.length()-fileName.length());
//			}
			this.mainFrame.getMainTabbedPane().setSelectedIndex( MainFrame.MainTabPane_ResourceMasterMainPanel_Index ); // add 
			this.mainFrame.getResourceMasterMainPanel().getMainTabbedPane().setSelectedIndex( ResourceMasterMainPanel.MainTabPane_FileExplorer_Index ); // add 
			this.mainFrame.getResourceMasterMainPanel().getFileExplorerPanel().setCurrentFolder(filePath, null);
			
		}else if( obj == jpmi_MainTable_Add2FavoriteFile){ 
			
			//step: check input
			int[] selRows = getMainTable().getSelectedRows(); // support multi rows
			if (selRows==null || selRows.length<1) {
				return;
			}
			
			//step: do business
			String fileName = null;
			String filePath = null;
			int successNum = 0;
			int failNum = 0;
			for (int i = 0; i < selRows.length; i++) {
				fileName = getMainTable().getModel().getValueAt(selRows[i], MainTable_Column_Index_Name).toString();
				filePath = getMainTable().getModel().getValueAt(selRows[i], MainTable_Column_Index_FilePath).toString();
				try {  //不采用批量处理，成功率低，如果一条有主键冲突则全部失败不好。
					this.mainFrame.getResourceMasterMainPanel()
							.getFavoriteFilesPanel().addNewFileToFavorite(filePath + File.separator + fileName, null);
					successNum++;
				} catch (Exception e1) {
					failNum++;
					e1.printStackTrace();
				}				
			}
			
			//step: give notice
			StringBuffer info = new StringBuffer("Add to favorite finished. "+successNum+" rows succeed");
			if (failNum==0) {
				info.append(".");
			} else {
				info.append(","+failNum+" fail.");
			}
			JOptionPane.showMessageDialog(this, info
												,"Finished",JOptionPane.INFORMATION_MESSAGE);
			setStatus( StatusBar_Index_One, info.toString() );
			
		}else if( obj == jpmi_MainTable_Rename){
						mainTable.editCellAt(getMainTable().getSelectedRow(), getMainTable().getSelectedColumn());
			
		}else if( obj == jpmi_MainTable_Delete){
			int[] rows=getMainTable().getSelectedRows();//获取所有选择的行
			if (rows.length<1) {
				JOptionPane.showMessageDialog(this,"Please select row to delete！");
				return ;
			}
			if(JOptionPane.showConfirmDialog(this,"Are you sure to delete "+rows.length
					           + " selected rows?","Tips",JOptionPane.OK_CANCEL_OPTION)
	 				!=JOptionPane.OK_OPTION)
	 			return;

			String fileName = null;
			String filePath = null;
			String fileFullName = null;
			boolean deleteFlag ;
			File file = null;
			PlainTableModel stm = getMainTable().getModel();
			DefaultTableModel dtm =  (DefaultTableModel)stm.getTableModel();
			int rowOffset = 0;
			for (int i = 0; i < rows.length; i++) {
				fileName = getMainTable().getModel().getValueAt(rows[i]-rowOffset, 0).toString();
				filePath = getMainTable().getModel().getValueAt(rows[i]-rowOffset, 1).toString();
				fileFullName = filePath + File.separator + fileName;
				file = new File(fileFullName);
				log.info("delete file="+fileFullName);
    			//deal subpath and subfile
    			if (file.isDirectory()) {
    				try {
    					LocalFileIndexEngine.loopFiles(fileFullName, file.list(), "delete");
					} catch (Exception e1) { 
						e1.printStackTrace();
					}
    			}
    			
    			// delete file
				if (file.isDirectory()) {
					deleteFlag = DirectorFileUtils.deleteDirectory(fileFullName);
					
				}else{
					deleteFlag = file.delete(); 
				}
				if (deleteFlag ) {
					dtm.removeRow(rows[i]-rowOffset);
					//delete lucene index
					LocalFileIndexManager im;
					try {
						im = new LocalFileIndexManager(LocalFileIndexBuilder.LocalFileSystem_INDEX);
		    			im.deleteIndexByIndex( fileFullName );
		    			im.close();
		    			
					} catch (IOException e1) {
						log.error(e1);
					}
					
					rowOffset++;
				}else{
					JOptionPane.showMessageDialog(this, "delete "+fileFullName+" fail for some reasons!please check the file." );
				}				
			}
			currentStatusInfor = "Delete successfully!";
			setStatus( StatusBar_Index_One, currentStatusInfor);
			
		}else if( obj == null){	// 退出系统
			//executeExitSystem();
		}
	}
	
	/**
	 * Table的弹出式菜单
	 */
	private JPopupMenu getPopupMenuForTable(){
		
		if(popupMenuForTable == null){
			popupMenuForTable = new JPopupMenu();
			
			jpmi_MainTable_Open = new JMenuItem();
			jpmi_MainTable_Open.setText("open");
			jpmi_MainTable_Open.addActionListener( this );
			jpmi_MainTable_Open.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_O,Event.CTRL_MASK) );
			jpmi_MainTable_OpenPath = new JMenuItem();
			jpmi_MainTable_OpenPath.setText("open path");
			jpmi_MainTable_OpenPath.addActionListener( this );
			jpmi_MainTable_OpenPath.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_P,Event.CTRL_MASK) );
			
			jpmi_MainTable_OpenPath_In_FileExplorer = new JMenuItem();
			jpmi_MainTable_OpenPath_In_FileExplorer.setText("open path in file explorer");
			jpmi_MainTable_OpenPath_In_FileExplorer.addActionListener( this );
			jpmi_MainTable_OpenPath_In_FileExplorer.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_E,Event.CTRL_MASK) );
			
			jpmi_MainTable_Add2FavoriteFile = new JMenuItem();
			jpmi_MainTable_Add2FavoriteFile.setText("add to favorite files");
			jpmi_MainTable_Add2FavoriteFile.addActionListener( this );
			jpmi_MainTable_Add2FavoriteFile.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_A,Event.CTRL_MASK) );
			
			jpmi_MainTable_Rename = new JMenuItem();
			jpmi_MainTable_Rename.setText("rename");
			jpmi_MainTable_Rename.addActionListener( this );
			jpmi_MainTable_Rename.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_R,Event.CTRL_MASK) );
			
			jpmi_MainTable_Delete = new JMenuItem();
			jpmi_MainTable_Delete.setText("delete");
			jpmi_MainTable_Delete.addActionListener( this );
			jpmi_MainTable_Delete.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_D,Event.CTRL_MASK) );
			
			popupMenuForTable.add( jpmi_MainTable_Open );
			popupMenuForTable.add( jpmi_MainTable_OpenPath );
			popupMenuForTable.add( jpmi_MainTable_OpenPath_In_FileExplorer );
			popupMenuForTable.addSeparator();
			popupMenuForTable.add( jpmi_MainTable_Add2FavoriteFile );
			popupMenuForTable.add( getAddFileOpenTaskAwokeMenuItem() );
			popupMenuForTable.addSeparator();
			popupMenuForTable.add( jpmi_MainTable_Rename );
			popupMenuForTable.add( jpmi_MainTable_Delete );
			
		}
		
		return popupMenuForTable;
			
		
	}
	private Object tableOldValue = null;
	public void mouseClicked(MouseEvent e) {
		Object obj = e.getSource();
		
		if (mainTable==obj) {
	        //记录进入编辑状态前单元格得数据
			if(mainTable.getSelectedRow()<=mainTable.getRowCount()
					&& mainTable.getSelectedRow()>-1 ){
				tableOldValue = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Name).toString();
			}

			// 双击打开文件
			if(!e.isPopupTrigger() && e.getClickCount()==2) {
				doOpenFileOrFolder(File_Type_File, false, e.isShiftDown());
				e.consume();
			}
		}
	}

	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseReleased(MouseEvent e) {
		Object obj = e.getSource() ;
		if(obj==getMainTable()){
			if(mainTable.getSelectedRow()<=mainTable.getRowCount()
					&& mainTable.getSelectedRow()>-1 ){
				tableOldValue = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Name)+"";
			}
			// 在Table上右击鼠标
			//System.out.println ( " getPopupMenuForTable 1");
			if( e.getButton() == MouseEvent.BUTTON3 ) {	//显示弹出菜单
				
				//System.out.println (getTable().getX()+e.getX());
				//getPopupMenuForTable().locate( getTable().getX()+e.getX(), getTable().getY()+e.getY() );
				//getPopupMenuForTable().setVisible( true );
				getPopupMenuForTable().setSelected(null);
				getPopupMenuForTable().show( e.getComponent(), e.getX(), e.getY() );
				
			}
		}
		
	}

	@Override
	public boolean fetchData() throws SQLException  {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean saveData() throws SQLException  {
		// TODO Auto-generated method stub
		return false;
	}

	public void keyPressed(KeyEvent e) {
		int keyCode = e.getKeyCode();
		Object obj = e.getSource();

	    if ( obj == mainTable ) {
			if(mainTable.getSelectedRow()<=mainTable.getRowCount()
					&& mainTable.getSelectedRow()>-1 ){
				tableOldValue = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Name)+"";
			}
	    }
		
		//System.out.println("11111111111111--"+e.getKeyCode());
	    if (e.getKeyCode() == KeyEvent.VK_ENTER ) {
	    	if(obj==mainTable){
	    		//System.out.println("2222222222222");
		    	int selRow = getMainTable().getSelectedRow(); //获得开始回车所在的行。
	    		log.info("selRow="+selRow);
		    	if (selRow>-1) {
		    		// keyPressed换行前调用， keyTyped换行后调用
			    	//getTable().setRowSelectionInterval(selRow, selRow);
			    	//doOpenCurrentFile();
		    		doOpenFileOrFolder(File_Type_File, false, e.isShiftDown());
		    		e.consume();
					
				}
	    	}else if(obj==this.getKeywordTextField()){
		    	int rowCount = getMainTable().getRowCount();			    	
		    	if (rowCount>0) {
					getMainTable().setRowSelectionInterval(0,0);
					getMainTable().requestFocusInWindow();
			    	e.consume();
				}
	    	}
	    	
	    }else if (keyCode == KeyEvent.VK_F && e.isControlDown()
	    		&& (obj==mainTable||obj==this) ) {
			getKeywordTextField().setFocusable(true); 
			getKeywordTextField().requestFocusInWindow();
	    	e.consume();
	    	
		}else  if (e.getKeyCode() == KeyEvent.VK_DOWN 
				 && obj==this.getKeywordTextField() ){
//	    	TableModel tm = getTable().getModel();
	    	int selectedRowNew = getMainTable().getSelectedRow() +1;
	    	int rowCount = getMainTable().getRowCount();			    	
	    	if (rowCount>0) {
	    		selectedRowNew = rowCount>selectedRowNew?selectedRowNew:0;
				getMainTable().requestFocus();
				getMainTable().setRowSelectionInterval(selectedRowNew,selectedRowNew);
			}
	    }
	
	}

	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void update(Observable o, Object arg) {
		super.update(o, arg);
		
		//System.out.println(Locale.getDefault());
		ResourceBundle bundle = I18nUtils.getBundle(DirectorConstants.I18n_Language_Name);

		//table
	    Vector<String> columnIdentifiers = new Vector<String>();
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "table.col00.Text"));
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "table.col01.Text"));
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "table.col02.Text"));
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "table.col03.Text"));
	    DefaultTableModel dtm = (this.getMainTable().getModel()).getTableModel();
	    dtm.setColumnIdentifiers(columnIdentifiers);
	    
	    //resize table columns
	    TableColumn tc = null;
	    TableColumnModel tcm = this.getMainTable().getColumnModel(); 
        for(int i=0; i < MainTable_Columns_Width.length; i++)   { // ?-1
            tc   =   tcm.getColumn(i);
            tc.setPreferredWidth(MainTable_Columns_Width[i]); 
        }
        this.getMainTable().showZebraCross();
        
        // popup menu for table 
        getPopupMenuForTable();
        jpmi_MainTable_Open.setText(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "jpmi_MainTable_Open.Text"));
        jpmi_MainTable_OpenPath.setText(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "jpmi_MainTable_OpenPath.Text"));
        jpmi_MainTable_OpenPath_In_FileExplorer.setText(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "jpmi_MainTable_OpenPath_In_FileExplorer.Text"));
        jpmi_MainTable_Add2FavoriteFile.setText(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "jpmi_MainTable_Add2FavoriteFile.Text"));
        jpmi_MainTable_Rename.setText(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "jpmi_MainTable_Rename.Text"));
        jpmi_MainTable_Delete.setText(I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "jpmi_MainTable_Delete.Text"));

		this.status_Searching = I18nUtil.getBundleString(bundle, MiniDialog.class, "searchButton.Text")+"...";
		
    	stutas_searchResultInfo = I18nUtil.getBundleString(bundle, LocalSearchMainPanel.class, "stutas_searchResultInfo.Text"); 
    	///this.currentStatusInfor = stutas_searchResultInfo ;
	}
	
}
